//
//  LogCatAesHelper.m
//  LogCat
//
//  Created by 清风徐来 on 2023/11/4.
//

#import "LogCatAesHelper.h"
#import <CommonCrypto/CommonCryptor.h>

#define LogCatgIv @"LogCat_GLV-"
#define LogCatAESPassword @"aes_password_twm"
#define LogCatAuthenticationKey @"Authentication_Key"

@implementation LogCatAesHelper

/**
 * AES 加密
 * - Parameters:
 *   - plainText: 待加密字符
 *   - password: 加密密钥
 *   - key: 鉴权
 */
+(NSString *)AES128Encrypt:(NSString *)plainText password:(NSString *)password key:(NSString *)key {
    // 鉴权
    if (![key isEqualToString:LogCatAuthenticationKey]) {
        return @"【鉴权Key错误！】";
    }
    // 检查密码是否正确
    if (![password isEqualToString:LogCatAESPassword]) {
        return @"【密码错误！】";
    }

    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [LogCatAESPassword getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCBlockSizeAES128+1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [LogCatgIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];

    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    long newSize = 0;

    if (diff > 0) {
        newSize = dataLength + diff;
    }

    char dataPtr[newSize];
    memcpy(dataPtr, [data bytes], [data length]);
    for(int i = 0; i < diff; i++) {
        dataPtr[i + dataLength] = 0x00;
    }

    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);

    size_t numBytesCrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          ivPtr,
                                          dataPtr,
                                          newSize,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);

    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        NSString *result = [resultData base64EncodedStringWithOptions:0];
        return result;
    }
    free(buffer);
    return nil;
}

/**
 * AES 解密
 * - Parameters:
 *   - cipherText: 待解密字符
 *   - password: 解密密钥
 *   - key: 鉴权
 */
+(NSString *)AES128Decrypt:(NSString *)cipherText password:(NSString *)password key:(NSString *)key {
    // 鉴权
    if (![key isEqualToString:LogCatAuthenticationKey]) {
        return @"【鉴权Key错误！】";
    }
    // 检验密钥
    if (![password isEqualToString:LogCatAESPassword]) {
        return @"【密码错误！";
    }

    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [LogCatAESPassword getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCBlockSizeAES128+1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [LogCatgIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSData *data = [[NSData alloc] initWithBase64EncodedString:cipherText options:0];
    NSUInteger dataLength = [data length];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);

    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesDecrypted);

    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        NSString *result = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
        return result;
    }

    free(buffer); // Make sure to free the buffer if decryption fails
    return nil;
}

/// 修复URL
+ (NSString *)fixUrl:(NSString *)str {
    // 移除字符串两端的空格和空字符
    NSString *trimmedString = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    // 循环检查并移除字符串中的"%00"
    NSRange range = [trimmedString rangeOfString:@"%00"];
    while (range.location != NSNotFound) {
        trimmedString = [trimmedString stringByReplacingOccurrencesOfString:@"%00" withString:@""];
        range = [trimmedString rangeOfString:@"%00"];
    }
    // 将URL字符串进行百分号编码
    NSString *encodedString = [trimmedString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    return encodedString;
}

/**
 * 密码
 * - Parameter key: 鉴权
 */
+(NSString *)passwordWithKey:(NSString *)key {
    // 鉴权
    if (![key isEqualToString:LogCatAuthenticationKey]) {
        return @"【鉴权Key错误！】";
    }
    return LogCatAESPassword;
}

@end
